package analyzers;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import constants.Globals;
import exception.IBToolsException;

import structures.GridTableColumnValues;
import structures.xmltable.ServiceBaseTypeParameter;
import structures.xmltable.ServiceParameterTable;
import structures.xmltable.ServiceParameterTableHeader;
import structures.xmltable.ServiceTableColumn;
import structures.xmltable.ServiceTableTypeParameter;
import structures.xmltable.ServiceTableValue;
import util.GlobalUtils;

public class GridAnalyzer implements Globals{

	static void main(String[]args){
//		String grid = "String   DELIVERYCODE             111\r\nString   CTID                     3356477964617806\r\nString   MUSTERINO                10068902\r\nString   TCID                     000\r\nString   SESSION_ID               93200000198701860\r\nString   UID                      A07111\r\nString   TABLE[13135][0]          1\r\nString   TABLE[9406][0]           003\r\nString   TABLE[4190][0]           1200\r\nString   TABLE[1726][0]           -1\r\nString   TABLE[4189][0]           1000\r\nString   TABLE[13944][0]          1\r\nString   TABLE[3205][0]           001,002";
//		ServiceParameterTable table = analyze(grid);
	}

	static List<String> toughString(String str){
//		String[] arr = str.split("Long|Int|String|Currency|Boolean|SBDate");
		int index = 0;
		List<String> gridLines = new ArrayList<String>();
//		String compareStr = str;
		String compareStr = str.substring(1);
		do{
			index = compareStr.length();
			if(compareStr.indexOf("Long") > -1 && compareStr.indexOf("Long") < index)
				index = compareStr.indexOf("Long") + 1;
			if(compareStr.indexOf("Int") > -1 && compareStr.indexOf("Int") < index)
				index = compareStr.indexOf("Int") + 1;
			if(compareStr.indexOf("String") > -1 && compareStr.indexOf("String") < index)
				index = compareStr.indexOf("String") + 1;
			if(compareStr.indexOf("Currency") > -1 && compareStr.indexOf("Currency") < index)
				index = compareStr.indexOf("Currency") + 1;
			if(compareStr.indexOf("Boolean") > -1 && compareStr.indexOf("Boolean") < index)
				index = compareStr.indexOf("Boolean") + 1;
			if(compareStr.indexOf("SBDate") > -1 && compareStr.indexOf("SBDate") < index)
				index = compareStr.indexOf("SBDate") + 1;
			if(index < 1){
				String last = gridLines.get(gridLines.size() - 1);
				gridLines.set(gridLines.size() - 1, last + str);
				break;
			}
			
			gridLines.add(str.substring(0, index));
			str = compareStr.substring(index - 1);
			compareStr = compareStr.substring(index);
		}
		while(index > -1);
		return gridLines;
	}

	public static ServiceParameterTable analyze(String[] analyzeOnly, String gridString) throws IBToolsException{
		String[] gridLines = gridString.split("\r\n");
		return commonAnalyze(analyzeOnly, gridLines);
	}
	public static ServiceParameterTable toughAnalyze(String gridString) throws IBToolsException{
		List<String> gridLines = toughString(gridString);
//		String header = null;
//		if(gridLines.size() > 0 && gridLines.get(0).startsWith("PROCESS")){
//			header = gridLines.get(0);
//			gridLines.remove(0);
//		}
	    String[] gridArray = gridLines.toArray(new String[gridLines.size()]);
	    ServiceParameterTable response = commonAnalyze(null, gridArray);
//	    if(header != null){
//	    	response.setServicename(header);
//	    }
	    
		return response;
	}
	static ServiceParameterTable commonAnalyze(String[] analyzeOnly, String[] gridLines) throws IBToolsException{

		List<String[]> grid = new ArrayList<String[]>();
		String serviceName = "ANALYZED_FROM_GRID";
		for (String lineString : gridLines) {
			String[] line = new String[3];
			boolean addToGrid = true;
			if(lineString.indexOf("[") > -1){	
				String test = lineString.substring(lineString.indexOf("[") + 1);
				if(test.indexOf("[") > -1){
					line[0] = lineString.substring(0, lineString.indexOf(" ")).trim();
					line[1] = lineString.substring(lineString.indexOf(" "), lineString.lastIndexOf("]") + 1).trim();
					line[2] = lineString.substring(lineString.lastIndexOf("]") + 1).trim();
				}
				else {
					
				}
			}
			else {
				if(lineHasType(lineString)){
					line[0] = lineString.substring(0, lineString.indexOf(" ")).trim();
					lineString = lineString.substring(lineString.indexOf(" ")).trim();
					if(lineString.indexOf(" ") > -1){
						line[1] = lineString.substring(0, lineString.indexOf(" ")).trim();
						lineString = lineString.substring(lineString.indexOf(" ")).trim();
					}
					else {
						line[1] = lineString;
						lineString = "";
					}
					line[2] = lineString.trim();
				}
				else {
					addToGrid = false;
					serviceName = lineString;
				}
			}
			if(addToGrid)
				grid.add(line);
		}
		
		ServiceParameterTableHeader headerInfo = new ServiceParameterTableHeader();
		ServiceParameterTable table = new ServiceParameterTable();
		table.setServicename(serviceName);
		
		GridTableColumnValues gridTableColumnValues = new GridTableColumnValues();
		
		boolean hasTableParameter = false;
		
		for (String[] line : grid) {
			if(line[1].equals("TCID"))
				headerInfo.setTcid(line[2]);
			else if(line[1].equals("CTID"))
				headerInfo.setCtid(line[2]);
			else if(line[1].equals("UID"))
				headerInfo.setUid(line[2]);
			else if(line[1].equals("FCID"))
				headerInfo.setFcid(line[2]);
			else if( !line[1].contains("[")){
				if(line[2].equalsIgnoreCase(EMPTY_STRING) && line[1].indexOf("_RESERVED") > -1){
					String afterReserved = line[1].substring(line[1].indexOf("_RESERVED") + 9);
					if(GlobalUtils.isNumeric(afterReserved)){
						line[1] = line[1].replaceAll(afterReserved, "");
						line[2] = afterReserved;
					}
				}
				else if(line[1].equals("SN"))
					table.setServicename(line[2]);
				table.add(new ServiceBaseTypeParameter(line[1], line[2], EMPTY_STRING, true, true, getTypeFromGrid(line[0])));
			}
			else {
				hasTableParameter = true;
				String[] gridTableLine = line[1].split("\\[");
				String bagKeyKey = gridTableLine[1].substring(0, gridTableLine[1].length()-1);
				Integer lineNumber = new Integer(gridTableLine[2].substring(0, 1));

				gridTableColumnValues.addTableColumnValue(gridTableLine[0], bagKeyKey, lineNumber, line[2]);
			}
		}
		
		if(hasTableParameter){
			gridTableColumnValues.finalize();
			gridTableToTable(table, gridTableColumnValues);
		}
		
		table.setHeaderInfo(headerInfo);

		if(table != null){
			if(serviceName != null)
				table.setServicename(serviceName);
	    	table.setDescription("GRID BAG");
			InputAnalyzer.analyzeBagKeys(analyzeOnly, table);
		}
		
    	return table;
	}
	private static boolean lineHasType(String compareStr){
		boolean sonuc = compareStr.indexOf("Long") > -1 ||
				compareStr.indexOf("Int") > -1 ||
				compareStr.indexOf("String") > -1 ||
				compareStr.indexOf("Currency") > -1 ||
				compareStr.indexOf("Boolean") > -1 ||
				compareStr.indexOf("SBDate") > -1 ||
				compareStr.indexOf("Date") > -1 ||
				compareStr.indexOf("Time") > -1;
		return sonuc;
	}
	public static void gridTableToTable(ServiceParameterTable table, GridTableColumnValues gridTableColumnValues){
		
		for (String tableName : gridTableColumnValues.getTableNames()) {
    		ServiceTableTypeParameter param = new ServiceTableTypeParameter(
    				tableName, EMPTY_STRING, EMPTY_STRING, true, true, false);
    		
        	List<ServiceTableColumn> columns = new ArrayList<ServiceTableColumn>();
        	List<List<ServiceTableValue>> values = new ArrayList<List<ServiceTableValue>>();
        	
    		for (String columnName : gridTableColumnValues.getTableColumns(tableName)) {
    			columns.add(new ServiceTableColumn(param, columnName, columns.size()));
    			Set<Integer> lines = gridTableColumnValues.getTableColumnLines(tableName, columnName);
    			int i = 0;
    			for (Integer lineNumber : lines) {
    				if(values.size() == i){
    					values.add(new ArrayList<ServiceTableValue>());
    				}
//    				int k = i;
//    				while (k < lineNumber){
//            			values.get(k).add("");
//            			k++;
//    				}
        			values.get(i).add(new ServiceTableValue(gridTableColumnValues.getTableColumnLineValue(tableName, columnName, lineNumber)));
        			i++;
				}
			}
    		param.setColumns(columns);
    		param.setValues(values);
    		table.add(param);
		}
	}

	private static String getTypeFromGrid(String gridType){

    	switch(gridType){
	    	case "Bag":
	    		return PARAM_BAG;
	    	case "String":
	    		return PARAM_STRING;
	    	case "Integer":
	    		return PARAM_INT;
	    	case "Long":
	    		return PARAM_LONG;
	    	case "CBDate":
	    		return PARAM_DATE;
	    	case "CBCurrency":
	    		return PARAM_CURRENCY;
	    	default:
	    		return PARAM_STRING;
    	}
	}
}
